﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using netcore_comm.JWT;
using netcore_comm.Nlog;
using netcore_comm.Redis;
using netcore_comm.SqlSugar;
using netcore_service.Dto;
using netcore_service.IRepository;
using netcore_service.IService;
using netcore_service.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace netcore_service.Service
{
    public class ManagerService : IManagerService
    {
        private readonly IManagerRepository _managerRepository;
        private readonly IJWTService _iJWTService;
        private readonly RedisHelper _redisHelper;
        private readonly ISqlSugarFactory _sqlSugarFactory;
        private readonly IWebHostEnvironment _hostingEnvironment;
        private readonly string privateKey = "<RSAKeyValue><Modulus>wVY7FmDVYEOuTIOvbS+XGmUBRcPIgvklXpSfmVGuuuV4enZyyRpf/9D1B2J55LfjnpDIQX5LSufHJOWatE17WvKtW2PnAjoRRLS0AyjGS1ApLGcYVmFPdMtGv4z88Vuy41/pxwX/+el558ah9Hj5GXVnajPAqtfm4TyQ1kKMF7E=</Modulus><Exponent>AQAB</Exponent><P>ygPwJb4InroZMD/kuruuGAAcQ0QhKaLB0StpCWz3Kyn2nqkrtGzsrQ2nLlvnUNt0SXE9L/dsHCEqH0/o2jaIdw==</P><Q>9QCV3HRXb7jMqxoSJIr3Q28Qk2NOXRX0FKh4hgmvhJBjbkuiMvTZz+mSu6AtHKukZ6NBB0JkIpELy2KvtuMTFw==</Q><DP>x4AGHC/EcYRVNboTl3mbHyaUwrU4jtal03ysWVub6KujWuK0P5VGUkxmarjmAosHFzRWedU9lbYG1C9lRIKQVw==</DP><DQ>EskNtI6TGbTgtInWNEkXdmswqSxnGMoTIfZc72IUvCRaC13vPNr7TG7LWmmIq/cZLv0cglL73I6kid6yPGKi1w==</DQ><InverseQ>RBTyv26fkdnWvVVDfc+DDqnYSUoLZOyM5xUNEG3MDR6O/9AhUJys/se52RHQAhM8j9hD5miu1BD0xjGYFyVLkA==</InverseQ><D>bXbXSZpV9YUcgLHmd1mEoisiB1AMjStnXx+jJXm8BpG6HwxFfVtzkzHKKf41qav8MmEjIQHSu3xzoo5lg0SDXEQFiZsiXNd5eZZyh5ZtsZbYYLx1UB/fTgI3gTzz9f9cXtQbY5lUVSVQ8AOH30xbpdeCY56887PewElAHYoEmgk=</D></RSAKeyValue>";
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly INLogHelper _nLogHelper;

        public ManagerService(IManagerRepository managerRepository, IJWTService iJWTService, RedisHelper redisHelper,
            ISqlSugarFactory sqlSugarFactory, IWebHostEnvironment hostingEnvironment, IHttpContextAccessor httpContextAccessor,
            INLogHelper nLogHelper)
        {
            _managerRepository = managerRepository;
            _iJWTService = iJWTService;
            _redisHelper = redisHelper;
            _sqlSugarFactory = sqlSugarFactory;
            _hostingEnvironment = hostingEnvironment;
            _httpContextAccessor = httpContextAccessor;
            _nLogHelper = nLogHelper;
        }


        [HttpPost]
        public async Task<ApiResult<UserDto>> CheckUser(UserPo user)
        {
            var db = _sqlSugarFactory.GetInstance(nameof(netData));
            if (!string.IsNullOrWhiteSpace(user.code))
            {
                string code = await _redisHelper.StringGetAsync($"verifycode_{user.codeKey}");
                if (code != user.code.Trim())
                {
                    return APIResult.GetError<UserDto>("验证码不正确,请重新输入验证码！");
                }
                //验证后，删除key
                await _redisHelper.KeyDeleteAsync($"verifycode_{user.codeKey}");
            }
            else
            {
                return APIResult.GetError<UserDto>("请输入验证码！");
            }
            //登录日志
            //var UserIp = GetClientUserIp(_httpContextAccessor.HttpContext);
            RSACryption rSACryption = new RSACryption();
            user.username = rSACryption.RSADecrypt(privateKey, user.username);
            user.password = rSACryption.RSADecrypt(privateKey, user.password);
            user.password = MD5Encrypt.Encrypt(user.password);
            Users model = await _managerRepository.GetModelAsync(db, e => e.UserName == user.username && e.PassWord == user.password && e.IsActive);
            if (model != null)
            {
                var token = this._iJWTService.GetToken(new CurrentUserModel()
                {
                    UserId = user.username.Trim(),
                    Name = user.username.Trim(),
                    Role = model.Type,
                });
                UserDto userDto = new UserDto
                {
                    token = token,
                    name = user.username.Trim(),
                    role = model.Type
                };
                //await _redisHelper.HashSet<string>($"successUserLogs{po.ksmc}:" + po.zjhm.Trim() + "_GetUserLogs", DateTime.Now.ToString(), $"{UserIp}{po.zjhm.Trim()}_登录成功");
                return APIResult.GetSuccess(userDto);
            }
            else
            {
                //await _redisHelper.HashSet<string>("ErrorUserLoginLogs", DateTime.Now.ToString(), $"{UserIp}{po.zjhm.Trim()}_登录失败");
                return APIResult.GetError<UserDto>("未匹配到您的身份信息！");

            }
        }

        [Authorize]
        [HttpGet]
        public string GetLess(string codeKey)
        {
            return MD5Encrypt.Encrypt(codeKey);
        }
        [HttpGet]
        public async Task<string> GetValidateCode(string codeKey)
        {
            try
            {
                //判断是否为空
                if (string.IsNullOrWhiteSpace(codeKey))
                {
                    return "判断是否为空";
                }

                ValidateCodeHelper cv = new ValidateCodeHelper();
                //创建4位的验证码
                string strValidateCode = cv.CreateValidateCode(4);

                //存入Redis中
                await _redisHelper.StringSetAsync($"verifycode_{codeKey}", strValidateCode, TimeSpan.FromSeconds(180));

                //生成验证码的图片
                byte[] codeImage = cv.CreateValidateGraphic(strValidateCode);
                return "data:image/jpeg;base64," + Convert.ToBase64String(codeImage);
            }
            catch (Exception ex)
            {
                //_Logger.Error(ex);
                return ex.ToString();

            }

        }

        [Authorize]
        [HttpPost("upload")]
        public async Task<ApiResult<string>> UploadImg(IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                return APIResult.GetError<string>("File is not selected or is empty");
            }
            // 验证文件类型
            if (file.ContentType != "image/jpeg" && file.ContentType != "image/png")
            {
                return APIResult.GetError<string>("Only JPG and PNG files are allowed");
            }
            // 生成唯一的文件名
            string uniqueFileName = Guid.NewGuid().ToString().Substring(0, 4) + "_" + file.FileName;

            // 指定文件保存路径
            string filePath = Path.Combine(_hostingEnvironment.WebRootPath + "/Logo");
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            filePath = Path.Combine(filePath, uniqueFileName);
            try
            {
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }
                string nginx = "wechatappletapi";
                // 在这里可以对文件流进行进一步处理，比如保存到数据库、进行文件转换等操作
                var baseUrl = $"https://{_httpContextAccessor.HttpContext?.Request.Host}/{nginx}/Logo/";
                var fileUrl = baseUrl + uniqueFileName;

                // 处理完成后返回成功信息
                return APIResult.GetSuccess<string>(fileUrl);
            }
            catch (Exception ex)
            {
                // 处理异常情况
                return APIResult.GetError<string>($"An error occurred while uploading the file: {ex.Message}");
            }
        }

        [HttpGet]
        public async Task<ApiResult<string>> getOpenId(string code)
        {

            string appId = "wxddd640715246f955";
            string appSecret = "b41a94d94b73deedc0f1928dae765e05";
            //获取微信的Openid
            //获取access_token和openid
            using (var client = new HttpClient())
            {
                var response = await client.GetAsync($"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={appSecret}&js_code={code}&grant_type=authorization_code");
                if (response.IsSuccessStatusCode)
                {
                    var resultJson = await response.Content.ReadAsStringAsync();
                    var result = JsonConvert.DeserializeObject<WeChatTokenResponse>(resultJson);
                    string accessToken = result.access_token;
                    string openId = result.openid;
                    await _redisHelper.ListLeftPushAsync<string>("getOpenId", openId);
                    return APIResult.GetSuccess<string>(openId);
                }
                else
                {
                    return APIResult.GetError("Failed to retrieve access token and openid.");
                }
            }
        }

        [HttpGet]
        public async Task<tokenDto> GetAccessToken()
        {
            string AppID = "wxddd640715246f955";
            if (await _redisHelper.StringGetAsync<tokenDto>($"{AppID}Key") == null)
            {
                tokenDto result = await getAs();
                await _redisHelper.StringSetAsync<tokenDto>($"{AppID}Key", result, TimeSpan.FromSeconds(result.expires_in));
            }
            return await _redisHelper.StringGetAsync<tokenDto>($"{AppID}Key");
        }

        [HttpGet]
        public async Task<phonenumber> GetPhonenumber(string code, string token)
        {
            try
            {

                using var httpClient = new HttpClient();
                dynamic dstr = new
                {
                    code = code
                };
                var str = JsonConvert.SerializeObject(dstr);
                HttpContent content = new StringContent(str);
                httpClient.BaseAddress = new Uri("https://api.weixin.qq.com");
                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                var memberResult = await httpClient.PostAsync($"/wxa/business/getuserphonenumber?access_token={token}", content);
                phonenumber number = JsonConvert.DeserializeObject<phonenumber>(await memberResult.Content.ReadAsStringAsync());

                if (number.errcode == 0)
                {
                    string usertoken = this._iJWTService.GetToken(new CurrentUserModel()
                    {
                        UserId = number.phone_info.purePhoneNumber,
                        Name = number.phone_info.purePhoneNumber,
                        Role = "mobile",
                    });
                    number.usertoken = usertoken;
                }
                else
                {
                    _nLogHelper.Error("获取手机号失败" + JsonConvert.SerializeObject(number));
                }

                return number;
            }
            catch (Exception ex)
            {
                _nLogHelper.Error("获取手机号失败" + ex.Message + '\n' + ex.InnerException);
                throw;
            }
        }


        private async Task<tokenDto> getAs()
        {
            string AppID = "wxddd640715246f955";
            string AppSecret = "b41a94d94b73deedc0f1928dae765e05";
            using var httpClient = new HttpClient();
            httpClient.BaseAddress = new Uri("https://api.weixin.qq.com");
            var memberResult = await httpClient.GetAsync($"/cgi-bin/token?grant_type=client_credential&appid={AppID}&secret={AppSecret}");
            tokenDto token = JsonConvert.DeserializeObject<tokenDto>(await memberResult.Content.ReadAsStringAsync());
            return token;
        }

        [HttpGet]
        public async Task<string> getweanalysday(int days = 1)
        {
            MonthPo monthPo = new MonthPo();

            for (int i = 1; i < days + 1; i++)
            {
                monthPo.begin_date = DateTime.Now.AddDays(-i).ToString("yyyyMMdd");
                monthPo.end_date = DateTime.Now.AddDays(-i).ToString("yyyyMMdd");
                await getweanalysisappiddailyvisittrend(monthPo);
            }

            return "success";
        }

        /// <summary>
        /// 用户访问小程序数据日趋势
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        private async Task<string> getweanalysisappiddailyvisittrend(MonthPo monthPo)
        {
            string accessToken = (await GetAccessToken()).access_token;
            using (var client = new HttpClient())
            {
                var response = await client.PostAsync($"https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend?access_token={accessToken}", new StringContent(JsonConvert.SerializeObject(monthPo), Encoding.UTF8, "application/json"));
                if (response.IsSuccessStatusCode)
                {
                    var resultJson = await response.Content.ReadAsStringAsync();
                    await _redisHelper.ListRightPushAsync<MiniProDto>("getweanalysisappiddailyvisittrend", JsonConvert.DeserializeObject<ProgramPo>(resultJson).list);
                    return resultJson;
                }
                else
                {
                    return "Failed to retrieve access token and openid.";
                }
            }

        }
        /// <summary>
        /// 用户访问小程序数据月趋势
        /// </summary>
        /// <returns></returns>
        [Authorize]
        [HttpPost]
        public async Task<string> getweanalysisappidmonthlyvisittrend(MonthPo monthPo)
        {
            var list = await _redisHelper.ListRangeAsync<MiniProDto>("getweanalysisappiddailyvisittrend");
            return JsonConvert.SerializeObject(list.Where(e => ConvertToDateTime(e.ref_date) >= ConvertToDateTime(monthPo.begin_date) & ConvertToDateTime(e.ref_date) <= ConvertToDateTime(monthPo.end_date)).OrderBy(e => e.ref_date));
        }

        private DateTime ConvertToDateTime(string ref_date)
        {
            // 指定日期格式
            string format = "yyyyMMdd";

            // 尝试解析日期
            if (DateTime.TryParseExact(ref_date, format, null, System.Globalization.DateTimeStyles.None, out DateTime result))
            {
                return result;
            }
            else
            {
                throw new ArgumentException("Invalid date format", nameof(ref_date));
            }
        }


        public async Task<ApiResult<List<WebUrlDto>>> GetWebUrl()
        {
            var list = await _redisHelper.ListRangeAsync<WebUrlDto>("weburl");
            return APIResult.GetSuccess<List<WebUrlDto>>(list);
        }
    }
}
